package com.yuanxin.permissions;

import android.Manifest;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.LocationManager;
import android.net.Uri;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.content.PermissionChecker;
import android.support.v7.app.AlertDialog;
import android.util.Log;

import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.PromiseImpl;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.modules.permissions.PermissionsModule;

import java.util.Locale;

public class ReactNativePermissionsModule extends ReactContextBaseJavaModule implements PermissionsCallback {
    private final ReactApplicationContext reactContext;
    private final PermissionsModule mPermissionsModule;
    private Promise promise;

    public enum RNType {
        LOCATION,
        CAMERA,
        MICROPHONE,
        CONTACTS,
        EVENT,
        STORAGE,
        PHOTO;
    }

    public ReactNativePermissionsModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
        mPermissionsModule = new PermissionsModule(this.reactContext);
    }

    @Override
    public String getName() {
        return "YuanXinSystemPermissionsManager";
    }


    @ReactMethod
    public void getPermissionStatus(String permissionString, Promise promise) {

        this.promise = promise;

        String permission = permissionForString(permissionString);

        // check if permission is valid
        if (permission == null) {
            promise.reject("unknown-permission", "ReactNativePermissions: unknown permission type - " + permissionString);
            return;
        }

        int result = PermissionChecker.checkSelfPermission(this.reactContext, permission);

       // Log.e("TAG", "getPermissionStatus---permission" + permission + "*result*" + result);

        switch (result) {
            case PermissionChecker.PERMISSION_DENIED:
                // PermissionDenied could also mean that we've never asked for permission yet.
                // Use shouldShowRequestPermissionRationale to determined which on it is.
                if (getCurrentActivity() != null) {
                    boolean deniedOnce = ActivityCompat.shouldShowRequestPermissionRationale(getCurrentActivity(), permission);
                    promise.resolve(deniedOnce ? "denied" : "undetermined");
                } else {
                    promise.resolve("denied");
                }
                break;
            case PermissionChecker.PERMISSION_DENIED_APP_OP:
                promise.resolve("denied");
                break;
            case PermissionChecker.PERMISSION_GRANTED:
                promise.resolve("authorized");
//                promise.resolve("undetermined");
                break;
            default:
                promise.resolve("undetermined");
                break;
        }
    }

    @ReactMethod
    public void requestPermission(final String permissionString, String nullForiOSCompat, final Promise promise) {

//        boolean oPen = isOPen(reactContext);
//        if(oPen){
//           // Log.e("TAG","GPS已打开");
//        }else {
//           // Log.e("TAG","打开GPS方法");
//            openGPS(reactContext);
//        }

//        openGPSSettings();

//        turnGPSOn();

//        openGPSSetting();

        String permission = permissionForString(permissionString);
        Callback resolve = new Callback() {
            @Override
            public void invoke(Object... args) {
                getPermissionStatus(permissionString, promise);
            }
        };
        Callback reject = new Callback() {
            @Override
            public void invoke(Object... args) {
                // NOOP
            }
        };

        mPermissionsModule.requestPermission(permission, new PromiseImpl(resolve, reject));
    }

    private void openGPSSetting() {
        LocationManager mLocationManager = (LocationManager) reactContext
                .getSystemService(Context.LOCATION_SERVICE);
        if (mLocationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {//GPS已开启
//            Toast.makeText(reactContext, "GPS已开启", Toast.LENGTH_SHORT).show();
            promise.resolve("authorized");
            return;
        }

        //请开启GPS！
//        Toast.makeText(reactContext, "请开启GPS！", Toast.LENGTH_SHORT).show();

        showNormalDialog();
    }

    private void showNormalDialog() {
        final AlertDialog.Builder normalDialog =
                new AlertDialog.Builder(reactContext.getCurrentActivity());
        normalDialog.setTitle("提示");
        normalDialog.setMessage("是否进入设置页面打开GPS？");
        normalDialog.setPositiveButton("是",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //...To-do
                       // Log.e("TAG", "进入设置开启GPS");

                        // 跳转到GPS的设置页面
                        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        getCurrentActivity().startActivityForResult(intent, 900); // 此为设置完成后返回到获取界面
                    }
                });
        normalDialog.setNegativeButton("否",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //...To-do
                       // Log.e("TAG", "不进入设置开启GPS");
                        promise.resolve("undetermined");
                    }
                });
        // 显示
        normalDialog.show();
    }

    @Override
    public void PermissionsMature() {
        LocationManager mLocationManager = (LocationManager) reactContext
                .getSystemService(Context.LOCATION_SERVICE);
        if (mLocationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {//GPS已开启
            promise.resolve("authorized");
        } else {//请开启GPS
            promise.resolve("undetermined");
        }

    }

    public void turnGPSOn() {
        Intent intent = new Intent("Android.location.GPS_ENABLED_CHANGE");
        intent.putExtra("enabled", true);
        LocalBroadcastManager.getInstance(reactContext).sendBroadcast(intent);

        String provider = Settings.Secure.getString(reactContext.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
        if (!provider.contains("gps")) { //if gps is disabled
            final Intent poke = new Intent();
            poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
            poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
            poke.setData(Uri.parse("3"));
            LocalBroadcastManager.getInstance(reactContext).sendBroadcast(poke);
        }
    }

    public static final boolean isOPen(final Context context) {
        LocationManager locationManager
                = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        // 通过GPS卫星定位，定位级别可以精确到街（通过24颗卫星定位，在室外和空旷的地方定位准确、速度快）
        boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        // 通过WLAN或移动网络(3G/2G)确定的位置（也称作AGPS，辅助GPS定位。主要用于在室内或遮盖物（建筑群或茂密的深林等）密集的地方定位）
        boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if (gps || network) {
            return true;
        }

        return false;
    }

    public static final void openGPS(Context context) {
        Intent GPSIntent = new Intent();
        GPSIntent.setClassName("com.android.settings",
                "com.android.settings.widget.SettingsAppWidgetProvider");
        GPSIntent.addCategory("android.intent.category.ALTERNATIVE");
        GPSIntent.setData(Uri.parse("custom:3"));
        try {
            PendingIntent.getBroadcast(context, 0, GPSIntent, 0).send();
        } catch (PendingIntent.CanceledException e) {
            e.printStackTrace();
        }
    }

    private void openGPSSettings() {
        //获取GPS现在的状态（打开或是关闭状态）
        boolean gpsEnabled = Settings.Secure.isLocationProviderEnabled(reactContext.getContentResolver(), LocationManager.GPS_PROVIDER);

        if (gpsEnabled) {

            //关闭GPS
            Settings.Secure.setLocationProviderEnabled(reactContext.getContentResolver(), LocationManager.GPS_PROVIDER, false);
        } else {
            //打开GPS  www.2cto.com
            Settings.Secure.setLocationProviderEnabled(reactContext.getContentResolver(), LocationManager.GPS_PROVIDER, true);

        }
    }

    @ReactMethod
    public void canOpenSettings(Promise promise) {
        promise.resolve(true);
    }

    @ReactMethod
    public void openSettings() {
        final Intent i = new Intent();
        i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        i.addCategory(Intent.CATEGORY_DEFAULT);
        i.setData(Uri.parse("package:" + this.reactContext.getPackageName()));
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        this.reactContext.startActivity(i);
    }

    private String permissionForString(String permission) {
        switch (RNType.valueOf(permission.toUpperCase(Locale.ENGLISH))) {
            case LOCATION:
                return Manifest.permission.ACCESS_FINE_LOCATION;
            case CAMERA:
                return Manifest.permission.CAMERA;
            case MICROPHONE:
                return Manifest.permission.RECORD_AUDIO;
            case CONTACTS:
                return Manifest.permission.READ_CONTACTS;
            case EVENT:
                return Manifest.permission.READ_CALENDAR;
            case STORAGE:
                return Manifest.permission.WRITE_EXTERNAL_STORAGE;//安卓系统获取写入权限会自动获取读取的权限，所以这里只写一个写入权限
            case PHOTO:
                return Manifest.permission.READ_EXTERNAL_STORAGE;
            default:
                return null;
        }
    }

}
